﻿Option Strict On
Option Explicit On
Option Infer On

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Xml.Linq
Imports GenDotNet.Task.Common
Imports GenDotNet.Model.Common
Imports GenDotNet.StoredProcModel
Imports <xmlns:orm="http://kadgen.com/KADORM.xsd">
Imports <xmlns:kd="http://kadgen.com/Special.xsd">
Imports <xmlns:s="http://kadgen.com/Select.xsd">


Public Class RootData
   Implements IRootData

   Private mEntities As Dictionary(Of String, EntityData)
   Private mTables As Dictionary(Of String, ITableData)
   'Private mTablesOriginalName As Dictionary(Of String, ITableData)
   Private mTablesNoSchema As Dictionary(Of String, ITableData)

   Public Shared Function LoadData( _
            ByVal category As String, _
            ByVal xDoc As XDocument, _
            ByRef hash As Int32) _
            As RootData
      ' This is the load entrypoint
      Dim rootData = New RootData()
      rootData.mEntities = New Dictionary(Of String, EntityData)
      rootData.mTables = New Dictionary(Of String, ITableData)
      rootData.mTablesNoSchema = New Dictionary(Of String, ITableData)
      'rootData.mTablesOriginalName = New Dictionary(Of String, ITableData)
      Dim root = xDoc.Root
      hash = xDoc.ToString.GetHashCode()
      Dim q = From x In root...<orm:SPSet> 

      For Each entityElement In q
         Dim name = entityElement.@Name
         If Not rootData.mEntities.ContainsKey(name) Then
            rootData.mEntities.Add(name, EntityData.Load(rootData, entityElement))
         End If
      Next
      Return rootData
   End Function


   Public Function GetXList() As System.Xml.Linq.XElement Implements Model.Common.IRootData.GetXList
      Return _
             <s:StoredProcs>
                <%= From entity In mEntities.Values _
                   Where entity.DoGenerateCreate _
                   Select <s:CreateStoredProc Name=<%= entity.Name %>/> %>
                <%= From entity In mEntities.Values _
                   Where entity.DoGenerateRetrieve _
                   Select <s:RetrieveStoredProc Name=<%= entity.Name %>/> %>
                <%= From entity In mEntities.Values _
                   Where entity.DoGenerateUpdate _
                   Select <s:UpdateStoredProc Name=<%= entity.Name %>/> %>
                <%= From entity In mEntities.Values _
                   Where entity.DoGenerateDelete _
                   Select <s:DeleteStoredProc Name=<%= entity.Name %>/> %>
                <%= From entity In mEntities.Values _
                   Where entity.DoGenerateSetSelect _
                   Select <s:RetrieveSetProc Name=<%= entity.Name %>/> %>
                <%= From entity In mEntities.Values _
                   Where entity.DoGenerateRetrieve _
                   Select <s:RetrieveChildrenStoredProc Name=<%= entity.Name %>/> %>
                <%= From entity In mEntities.Values _
                   Where entity.DoGenerateRetrieve _
                   Select <s:RetrieveHierarchyStoredProc Name=<%= entity.Name %>/> %>
             </s:StoredProcs>
   End Function

   '   <%= From entity In mEntities.Values _
   'From sp In entity.StoredProcedures _
   'Where sp.Task = StoredProcModel.StoredProcedureTask.RetrieveChild _
   'Select <s:RetrieveChildrenStoredProc <%= CType(sp, BaseData).Element.Attributes() %>/> %>
   '   <%= From entity In mEntities.Values _
   'From sp In entity.StoredProcedures _
   'Where sp.Task = StoredProcModel.StoredProcedureTask.RetrieveChild _
   'Select <s:RetrieveChildrenStoredProc <%= CType(sp, BaseData).Element.Attributes() %>/> %>

   Public Function GetItem( _
           ByVal name As String) _
           As IBaseData _
           Implements IRootData.GetItem
      Dim entity As EntityData = Nothing
      mEntities.TryGetValue(name, entity)
      Return entity
   End Function

   Public Sub AddNewTable(ByVal table As ITableData)
      If Not mTables.ContainsKey(TableKey(table.Schema, table.Name)) Then
         mTables.Add(TableKey(table.Schema, table.Name), table)
      End If
      If Not mTablesNoSchema.ContainsKey(table.Name) Then
         mTablesNoSchema.Add(table.Name, table)
      End If
   End Sub

   Private Function TableKey(ByVal schema As String, ByVal name As String) As String
      ' Schema is currently ignored because it is not always available due to metadata shortcomings
      Return name
   End Function

   Public Function GetTable(ByVal schema As String, ByVal name As String) As ITableData
      Dim table As ITableData = Nothing
      mTables.TryGetValue(TableKey(schema, name), table)
      Return table
   End Function

   Public Function GetTable(ByVal name As String) As ITableData
      Dim table As ITableData = Nothing
      mTablesNoSchema.TryGetValue(name, table)
      Return table
   End Function

   Public Function GetEntity(ByVal name As String) As EntityData
      Dim data As EntityData = Nothing
      mEntities.TryGetValue(name, data)
      Return data
   End Function

End Class

